package org.optionparser;

/**
 * Class Option used for storing information about one option
 * 
 * @author Rastislav Kadlecek
 * @author Marcel Kikta
 */
class Option {
	
	
	
	/**
	 * Short name of option, must be 1 character long or empty
	 * (f.e. "v")
	 */
	private String shortName;
	/**
	 * Short name of option
	 * (f.e. "version")
	 */
	private String longName;
	/**
	 * Type of the option parameter
	 * Required, Optional, Forbidden
	 */
	private ParameterType parameterType;
	/**
	 * Class of the parameter
	 * Boolean, Integer, String
	 */
	private ParameterClass parameterClass;
	/**
	 * Lower bound for integral parameter
	 */
	private Integer lowerBound;
	/**
	 * Upper bound for integral parameter
	 */
	private Integer upperBound;
	/**
	 * Parsed value of parameter
	 */
	private String value;
	/**
	 * Name of parameter (used in usage information printing)
	 */
	private String parameterName;
	/**
	 * List of allowed values for string parameter
	 */
	private String[] expectedValues;
	/**
	 * Description of the parameter
	 */
	private String description;
	/**
	 * Type of option
	 * Required, Optional		
	 */
	private OptionType optionType;
	
	private boolean foundOnCommandline;
	
	/**
	 * Constructor, which builds instance of Option class according to specified options
	 * 
	 * @param shortName						Short name of option
	 * @param longName						Long name of option
	 * @param optionType					Type of option (Required, Optional..)
	 * @param parameterType					Type of option paramater (Required, Optional..)
	 * @param parameterClass				Class of option parameter (String, Boolean ..)
	 * @param parameterName					Name of parameter
	 * @param lowerBound					If parameter class is Integer, this is the lower bound criterium
	 * @param upperBound					If parameter class is Integer, this is the upper bound criterium 
	 * @param expectedValues				Expected Values for parameter
	 * @param description					Description of parameter
	 */
	public Option(String shortName, String longName, OptionType optionType,
			ParameterType parameterType, ParameterClass parameterClass,
			String parameterName, Integer lowerBound, Integer upperBound, String[] expectedValues, String description) {

		this.shortName = returnValidString(shortName);
		this.longName = returnValidString(longName);
		this.optionType = optionType;
		this.parameterType = parameterType;
		this.parameterName = parameterName;
		this.lowerBound=lowerBound;
		this.upperBound=upperBound;
		this.expectedValues = returnValidStringArray(expectedValues);
		this.parameterClass = parameterClass;
		this.description = returnValidString(description);
		this.setFoundOnCommandline(false);
		this.value = "";
	}
	
	
	/**
	 * Returns the value of option parameter
	 * 
	 * @return	If defined, returns value of parameter, otherwise returns empty string
	 */
	public String getValue() {
		return value;
	}
	
	
	/**
	 * Sets the value of option parameter 
	 * 
	 * @param value			Value to be set as parameter value
	 */
	public void setValue(String value) {
		this.value = value;
	}
	
	/**
	 * Returns the short name of option (with  - prefix)
	 * For example: if short name is "v", this function returns "-v" 
	 * 
	 * @return	If defined, returns the short name of option, otherwise returns empty string
	 */
	public String getShortName() {
		return "-" + shortName;
	}
	
	/**
	 * Returns the long name of option, starting with -- prefix 
	 * For example: if long name is "version", this function returns "--version" 
	 * 
	 * @return	If defined, returns the long name of option, otherwise returns empty string
	 */
	public String getLongName() {
		return "--" + longName;
	}
	
	/**
	 * Returns the short name of option (without  - prefix)
	 * For example: if short name is "v", this function returns "v" 
	 * 
	 * @return	If defined, returns the short name of option, otherwise returns empty string
	 */
	public String getCanonicalShortName() {
		return shortName;
	}
	
	/**
	 * Returns the long name of option (without -- prefix)
	 * For example: if long name is "version", this function returns "version" 
	 * 
	 * @return	If defined, returns the long name of option, otherwise returns empty string
	 */
	public String getCanonicalLongName() {
		return longName;
	}
	
	
	/**
	 * Returns the type of option parameter 
	 * 
	 * @return	returns the type of parameter
	 */
	public ParameterType getParameterType() {
		return parameterType;
	}
	
	/**
	 * Returns the array of defined expected values for parameter 
	 * 
	 * @return	if defined, returns the String array of expected values, 
	 * 			otherwise returns empty array
	 */
	public String[] getExpectedValues() {
		return expectedValues;
	}
	
	/**
	 * Returns the class of option parameter 
	 * 
	 * @return	returns the class of parameter
	 */
	public ParameterClass getParameterClass() {
		return parameterClass;
	}

	/**
	 * Returns the name of option parameter
	 * Can be used for example in printing usage information 
	 * 
	 * @return	if defined, returns the name of parameter, 
	 * 			otherwise return empty string
	 */
	public String getParameterName() {
		return parameterName;
	}
	
	/**
	 * Returns option description
	 * 
	 * @return	if defined, returns the description, 
	 * 			otherwise return empty string
	 */
	public String getDescription() {
		return description;
	}


	/**
	 * Returns the type of option
	 * 
	 * @return	the type of option
	 */
	public OptionType getOptionType() {
		return optionType;
	}
	
	/**
	 * Returns valid string (if original string was null, return empty string)
	 * 
	 * @param originalString			String to check
	 * @return							Empty string, if originalString was empty or null, originalString otherwise
	 */
	public static String returnValidString(String originalString)
	{
		if (originalString != null)
		{
			if (!(originalString.isEmpty()))
			{
				return originalString;
			}
					
		}
		return "";
	}
	
	/**
	 * Returns valid array of Strings (if original array was null, return empty array)
	 * 
	 * @param originalArray				Array to check
	 * @return							Empty array of Strings, if originalArray was null, otherwise originalArray
	 */
	public static String[] returnValidStringArray(String[] originalArray)
	{
		if (originalArray != null)
		{
			return originalArray;
		}
		return new String[0];
	}

/**
 * 
 * @return foundOnCommandline
 */
	public boolean isFoundOnCommandline() {
		return foundOnCommandline;
	}

/**
 * @param foundOnCommandline
 */
	public void setFoundOnCommandline(boolean foundOnCommandline) {
		this.foundOnCommandline = foundOnCommandline;
	}
	/**
	 * Returns long name if s defines. Otherwise returns short name.
	 */
	public String toString()
	{
		if(longName == "") {
			return getShortName();
		}
		else {
			return getLongName();
		}
	}

	
	/**
	 * Returns long name if s defines. Otherwise returns short name.
	 */
	public String toCanonicalString()
	{
		if(longName == "") {
			return getCanonicalShortName();
		}
		else {
			return getCanonicalLongName();
		}
	}
	
	/**
	 * @return the lowerBound
	 */
	public Integer getLowerBound() {
		return lowerBound;
	}



	/**
	 * @return the upperBound
	 */
	public Integer getUpperBound() {
		return upperBound;
	}

	
}
